home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / BuildingBlocks / DisAsmLookup.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-28  |  23.1 KB  |  511 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DisAsmLookup.h
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14.  
  15. #ifndef __DISASMLOOKUP__
  16. #define __DISASMLOOKUP__
  17.  
  18. #ifndef __TYPES__
  19. #include <Types.h>
  20. #endif
  21.  
  22.  
  23. typedef enum {_A0_, _A1_, _A2_, _A3_, _A4_, _A5_, _A6_, _A7_, _PC_, _ABS_, _TRAP_, _IMM_} LookupRegs;
  24.         
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28.  
  29. /*----------------------------------------------------------------------------*/
  30.  
  31. typedef pascal void (* LookUpProcType)(Ptr PC,  LookupRegs BaseReg, long Opnd, char* S); 
  32.  
  33.  
  34. pascal void Disassembler( 
  35.         long DstAdjust,                         // Address correction
  36.         short& BytesUsed,                     // Bytes used up by 1 call 
  37.         Ptr FirstByte,                        // Ptr to 1st byte
  38.         char *Opcode,                         // Ptr to opcode String 
  39.         char *Operand,                         // Ptr to operand String
  40.         char *Comment,                         // Ptr to comment String
  41.         LookUpProcType LookUpProc            // Ptr to PASCAL proc or NULL
  42.     );        
  43.     /*
  44.     Disassembler is a Pascal routine to be called to disassemble a sequence of
  45.     bytes.  All MC68xxx, MC68881, and MC68851 instructions are supported.  The
  46.     sequence of bytes to be disassembled are pointed to by FirstByte.  BytesUsed
  47.     bytes starting at FirstByte are consumed by the disassembly, and the Opcode,
  48.     Operand, and Comment strings returned as NULL TERMINATED Pascal strings (for
  49.     easier manipulation with C).  The caller is then free to format or use the
  50.     output strings any way appropriate to the application.
  51.  
  52.     Depending on the opcode and effective address(s) (EA's) to be disassembled,
  53.     the Opcode, Operand, and Comment strings contain the following information:
  54.     
  55.     Case                     Opcode    Operand    Comment
  56.     =======================================================================
  57.     Non PC-relative EA's     op.sz     EA's                ; 'c…' (for immediates)
  58.     PC-relative EA's         op.sz     EA's       ; address
  59.     Toolbox traps            DC.W      $AXXX      ; TB XXXX
  60.     OS traps                 DC.W      $AXXX      ; OS XXXX
  61.     Invalid bytes            DC.W      $XXXX      ; ????
  62.     =======================================================================
  63.     
  64.     For valid disassembly of processor instructions the appropriate MC68XXX
  65.     opcode mnemonic is generated for the Opcode String along with a size
  66.     attribute when required. The source and destination EA's are generated as the
  67.     Operand along with a possible comment.  Comments start with a ';'.  Traps use
  68.     a DC.W assembler directive as the Opcode with the trap word as the Operand
  69.     and a comment indicating whether the trap is a toolbox or OS trap and what
  70.     the trap number is.  As described later the caller can generate symbolic
  71.     substitutions into EA's and provide names for traps.
  72.  
  73.     Invalid instructions cause the String 'DC.W' to be returned in the Opcode
  74.     String. Operand is '$XXXX' (the invalid word) with a comment of '; ????'.
  75.   BytesUsed is 2. This is similar to the trap call case except for the comment.
  76.  
  77.     Note, the Operand EA's is syntatically similar to but NOT COMPATIBLE with the
  78.     MPW assembler!    This is because the Disassembler generates byte hex constants
  79.     as "$XX" and word hex constants as "$XXXX".  Negative values (e.g., $FF or
  80.     $FFFF) produced by the Disassembler are treated as long word values by the MPW
  81.     assembler.  Thus it is assumed that Disassembler output will NOT be used as
  82.     MPW assembler input. If that is the goal, then the caller must convert strings
  83.     of the form $XX or $XXXX in the Operand String to their decimal equivalent.
  84.     The routine ModifyOperand is provided in this unit to aid with the conversion
  85.     process.
  86.  
  87.     Since a PC-relative comment is an address, the only address that the
  88.     Disassembler knows about is the address of the code pointed to by FirstByte.
  89.   Generally, that may be a buffer that has no relation to "reality", i.e., the
  90.     actual code loaded into the buffer.  Therefore, to allow the address comment
  91.     to be mapped back to some actual address the caller may specify an adjustment
  92.     factor, specified by DstAdjust that is ADDED to the value that normally would
  93.     be placed in the comment.
  94.  
  95.     Operand effective address strings are generated as a function of the 
  96.     effective address mode and a special case is made for A-trap opcode strings.
  97.     In places where a possible symbolic reference could be substituted for an
  98.     address (or a portion of an address), the Disassembler can call a user
  99.     specified routine to do the substitution (using th LookupProc parameter
  100.     described later).  The following table summarizes the generated effective
  101.     addresses and where symbolic substitutions (S) can be made:
  102.              
  103.     Mode    Generated Effective Address  Effective Address with Substitution
  104.   ========================================================================
  105.         0     Dn                           Dn
  106.         1     An                           An
  107.         2     (An)                         (An)
  108.         3     (An)+                        (An)+
  109.         4     -(An)                        -(An)
  110.         5     ∂(An)                        S(An) or just S (if An=A5, ∂≥0)
  111.      6n     ∂(An,Xn.Size*Scale)          S(An,Xn.Size*Scale)
  112.      6n     (BD,An,Xn.Size*Scale)        (S,An,Xn.Size*Scale)
  113.      6n     ([BD,An],Xm.Size*Scale,OD)   ([S,An],Xm.Size*Scale,OD)
  114.      6n     ([BD,An,Xn.Size*Scale],OD)   ([S,An,Xn.Size*Scale],OD)
  115.      70     ∂                            S
  116.      71     ∂                            S
  117.      72     *±∂                          S
  118.      73     *±∂(Xn.Size*Scale)           S(Xn.Size*Scale)
  119.      73     (*±∂,Xn.Size*Scale)          (S,Xn.Size*Scale)
  120.      73     ([*±∂],Xm.Size*Scale,OD)     ([S],Xm.Size*Scale,OD)
  121.      73     ([*±∂,Xn.Size*Scale],OD)     ([S,Xn.Size*Scale],OD)
  122.      74     #data                        S (#data made comment)
  123.     A-traps $AXXX                        S (as opcode, AXXX made comment)
  124.   ========================================================================
  125.  
  126.   For A-traps, the substitution can be performed to substitute for the DC.W
  127.     opcode String.  If the substitution is made then the Disassembler will
  128.     generate ,Sys and/or ,Immed flags as operands for Toolbox traps and
  129.     ,AutoPop for OS traps when the bits in the trap word indicates these
  130.     settings.
  131.     
  132.                     |         Generated          |            Substituted
  133.                     | Opcode  Operand  Comment   | Opcode  Operand        Comment
  134.   ========================================================================
  135.     Toolbox | DC.W    $AXXX    ; TB XXXX | S       [,Sys][,Immed] ; AXXX
  136.     OS      | DC.W    $AXXX    ; OS XXXX | S       [,AutoPop]     ; AXXX
  137.   ========================================================================
  138.  
  139.     All displacements (∂, BD, OD) are hexadecimal values shown as a byte ($XX),
  140.     word ($XXXX), or long ($XXXXXXXX) as appropriate. The *Scale is suppressed if
  141.     1. The Size is W or L.  Note that effective address substitutions can only be
  142.     made for "∂(An)", "BD,An", and "*±∂" cases.
  143.             
  144.     For all the effective address modes 5, 6n, 7n, and for A-traps, a coroutine (a
  145.     procedure) whose address is specified by the LookupProc parameter is called by
  146.     the Disassembler (if LookupProc is not NIL) to do the substitution (or A-trap
  147.     comment) with a String returned by the proc.  It is assumed that the proc
  148.     pointed to by LookupProc is a level 1 Pascal proc declared as follows:
  149.  
  150.     PROCEDURE Lookup(         PC:      UNIV Ptr;     {Addr of extension/trap word}
  151.                                              BaseReg: LookupRegs;   {Base register/lookup mode  }
  152.                                              Opnd:    UNIV LongInt; {Trap word, PC addr, disp.  }
  153.                                      VAR S:       CStr255);             {Returned substitution      }
  154.         
  155.     or in C,
  156.     
  157.     pascal void LookUp(Ptr         PC, 
  158.                        LookupRegs  BaseReg, 
  159.                                          long        Opnd, 
  160.                                          char        *S); 
  161.  
  162.     PC      = Pointer to instruction extension word or A-trap word in the
  163.                         buffer pointed to by the Disassembler's FirstByte parameter.
  164.                         
  165.     BaseReg = This determines the meaning of the Opnd value and supplies
  166.                         the base register for the "∂(An)", "BD,An", and "*±∂" cases.
  167.                         BaseReg may contain any one of the following values:
  168.                      
  169.                         _A0_    =  0 ==> A0
  170.                         _A1_    =  1 ==> A1
  171.                         _A2_    =  2 ==> A2
  172.                         _A3_    =  3 ==> A3
  173.                         _A4_    =  4 ==> A4
  174.                         _A5_    =  5 ==> A5
  175.                         _A6_    =  6 ==> A6
  176.                         _A7_    =  7 ==> A7
  177.                         _PC_    =  8 ==> PC-relative (special case)
  178.                         _ABS_   =  9 ==> Abs addr    (special case)
  179.                         _TRAP_  = 10 ==> Trap word   (special case)
  180.                   _IMM_        = 11 ==> Immediate   (special case)
  181.                         
  182.                         For absolute addressing (modes 70 and 71), BaseReg contains _ABS_.
  183.                         For A-traps, BaseReg would contain _TRAP_.  For immediate data (mode
  184.                         74), BaseReg would contain _IMM_.
  185.  
  186.     Opnd    = The contents of this LongInt is determined by the BaseReg parameter
  187.                         just described.
  188.                  
  189.                         For BaseReg = _IMM_ (immediate data):
  190.                               Opnd contains the (extended) 32-bit immediate data specified by
  191.                                 the instruction.
  192.  
  193.                         For BaseReg = _TRAP_ (A-traps):
  194.                                 Opnd is the entire trap word. The high order 16 bits of Opnd are
  195.                                 zero.
  196.  
  197.                         For BaseReg = _ABS_  (absolute effective address):
  198.                                 Opnd contains the (extended) 32-bit address specifed by the
  199.                                 instruction's effective address.  Such addresses would generally
  200.                                 be used to reference low memory globals on a Macintosh.
  201.  
  202.                         For BaseReg = _PC_  (PC-relative effective address):
  203.                                 Opnd contains the 32-bit address represented by "*±∂" adjusted
  204.                                 by the Disassembler's DstAdjust parameter.
  205.                                 
  206.                         For BaseReg = _An_  (effective address with a base register):
  207.                                 Opnd contains the (sign-extended) 32-bit (base) displacement
  208.                                 from the instruction's effective address.
  209.                                 
  210.                                 In the Macintosh environment, a BaseReg specifying A5 implies
  211.                                 either global data references or Jump Table references. Positive
  212.                                 Opnd values with an A5 BaseReg thus mean Jump Table references,
  213.                                 while a negative offset would mean a global data reference.
  214.                                 Base registers of A6 or A7 would usually mean local data.
  215.  
  216.     S       = Pascal String returned from Lookup containing the effective address
  217.                         substitution String or a trap name for A-traps.  S is set to null
  218.                         PRIOR to calling Lookup.  If it is still null on return, the String
  219.                         is not used.  If not null, then for A-traps, the returned String is
  220.                         used as a opcode String. In all other cases the String is
  221.                         substituted as shown in the above table.
  222.                          
  223.     Depending on the application, the caller has three choices on how to use the
  224.     Disassembler and an associated Lookup proc:
  225.  
  226.     (1). The caller can call just the Disassembler and provide his own Lookup
  227.              proc. In that case the calling conventions discussed above must be
  228.              followed.
  229.  
  230.     (2). The caller can provide NIL for the LookupProc parameter, in which case,
  231.              NO Lookup proc will be called.
  232.              
  233.     (3). The caller can call first InitLookup (described below, a proc provided
  234.              with this unit) and pass the address of this unit's standard Lookup proc
  235.              when Disassembler is called.    In this case all the control logic to
  236.              determine the kind of substitution to be done is provided for the caller
  237.              and all that need to be provided by the user are routines to look up any
  238.              or all of the following:
  239.              
  240.              • PC-relative references
  241.              • Jump Table references
  242.              • Absolute address references
  243.              • Trap names
  244.              • Immediate data names
  245.              • References with offsets from base registers                                                    */
  246.                 
  247.  
  248. typedef pascal void (* PCRelProcType)(long Address, char *S);
  249.  
  250. typedef pascal void (* JTOffProcType)(short A5JTOffset, char *S);
  251.  
  252. typedef pascal void (* TrapNameProcType)(unsigned short TrapWord, char *S);
  253.  
  254. typedef pascal void (* AbsAddrProcType)(long AbsAddr, char *S);
  255.  
  256. typedef pascal void (* IdProcType)(LookupRegs BaseReg, long Offset, char *S);
  257.  
  258. typedef pascal void (* ImmDataProcType)(long ImmData, char *S);
  259.  
  260.  
  261. pascal void InitLookup(PCRelProcType PCRelProc, JTOffProcType JTOffProc, 
  262.         TrapNameProcType TrapProc, AbsAddrProcType AbsAddrProc, 
  263.         IdProcType IdProc, ImmDataProcType ImmDataProc);
  264.     /*
  265.     Prepare for use of this unit's Lookup proc.  When Disassembler is called
  266.     and the address of this unit's Lookup proc is specified, then for immeduate 
  267.     data, PC-relative, Jump Table references, A-traps, absolute addresses, and
  268.     offsets from a base register, the associated level 1 Pascal proc specified
  269.     here is called (if not NULL -- all five addresses are preset to NULL). The
  270.     calls assume the following declarations for these procs (see Lookup, below
  271.     for further details):
  272.                                                              
  273.     PROCEDURE PCRelProc(Address: UNIV LongInt;
  274.                                             VAR S:     UNIV CStr255);
  275.  
  276.     PROCEDURE JTOffProc(A5JTOffset: UNIV Integer;
  277.                                             VAR S:        UNIV CStr255);
  278.  
  279.     PROCEDURE TrapNameProc(TrapWord: UNIV Integer;
  280.                                                  VAR S:       UNIV CStr255);
  281.                                                     
  282.     PROCEDURE AbsAddrProc(AbsAddr: UNIV LongInt;
  283.                                                 VAR S:     UNIV CStr255);
  284.  
  285.     PROCEDURE IdProc(BaseReg: LookupRegs;
  286.                                      Offset:  UNIV LongInt;
  287.                                      VAR S:      UNIV CStr255);
  288.                                                              
  289.     PROCEDURE ImmDataProc(ImmData: UNIV LongInt;
  290.                                                 VAR S:     UNIV CStr255);
  291.                                          
  292.     or in C,
  293.     
  294.     pascal void PCRelProc(long Address, char *S)
  295.     
  296.     pascal void JTOffProc(short A5JTOffset, char *S)
  297.     
  298.     pascal void TrapNameProc(unsigned short TrapWord, char *S)
  299.     
  300.     pascal void AbsAddrProc(long AbsAddr, char *S)
  301.     
  302.     pascal void IdProc(LookupRegs BaseReg, long Offset, char *S)
  303.     
  304.     pascal void ImmDataProc(long ImmData, char *S)
  305.  
  306.     Note: InitLookup contains initialized data which requires initializing at load
  307.                 time (this is of concern only to users with assembler main programs).
  308. */
  309.  
  310.     
  311. pascal void Lookup(Ptr         PC,            /* Addr of extension/trap word                */
  312.                                      LookupRegs  BaseReg, /* Base register/lookup mode                  */
  313.                                      long        Opnd,        /* Trap word, PC addr, disp.                  */
  314.                                      char        *S);             /* Returned substitution                            */
  315.     /*
  316.     This is a standard Lookup proc available to the caller for calls to the
  317.     Disassembler.    If the caller elects to use this proc, then InitLookup MUST be
  318.     called prior to any calls to the Disassembler.  All the logic to determine the
  319.     type of lookup is done by this proc.  For PC-relative, Jump Table references,
  320.     A-traps, absolute addresses, and offsets from a base register, the associated
  321.     level 1 Pascal proc specified in the InitLookup call (if not NULL) is called.
  322.  
  323.     This scheme simplifies the Lookup mechanism by allowing the caller to deal
  324.     with just the problems related to the application.
  325.     */
  326.  
  327.  
  328. pascal void LookupTrapName(unsigned short TrapWord, char *S);
  329.     /*
  330.     This is a procedure provided to allow conversion of a trap instruction (in
  331.      TrapWord) to its corresponding trap name (in S).  It is provided primarily for
  332.      use with the Disassembler and its address may be passed to InitLookup above for
  333.      use by this unit's Lookup routine.  Alternatively, there is nothing prohibiting
  334.      the caller from using it directly for other purposes or by some other lookup
  335.      proc.
  336.  
  337.  Note: The tables in this proc make the size of this proc about 9500 bytes.  The
  338.              trap names are fully spelled out in upper and lower case.
  339.  */
  340.  
  341.  
  342. pascal void ModifyOperand(char *operand);
  343.     /*
  344.     Scan an operand String, i.e., the null terminated Pascal String returned by
  345.     the Disassembler (null MUST be present here) and modify negative hex values to
  346.     negated positive value. For example, $FFFF(A5) would be modified to -$0001(A5).
  347.   The operand to be processed is    passed as the function's parameter which is
  348.     edited "in place" and returned to the caller.
  349.  
  350.     This routine is essentially a pattern matcher and attempts to only modify 2, 4,
  351.     and 8 digit hex strings in the operand that "might" be offsets from a base
  352.     register.  If the matching tests are passed, the same number of original digits
  353.     are output (because that indicates a value's size -- byte, word, or long).
  354.  
  355.     For a hex String to be modified, the following tests must be passed:
  356.  
  357.     • There must have been exactly 2, 4, or 8 digits.
  358.  
  359.         Only hex strings $XX, $XXXX, and $XXXXXXXX are possible candidates because
  360.         that is the only way the Disassembler generates offsets.
  361.  
  362.     • Hex String must be delimited by a "(" or a ",".
  363.  
  364.         The "(" allows offsets for $XXXX(An,...) and $XX(An,Xn) addressing modes.
  365.         The comma allows for the MC68020 addressing forms.
  366.  
  367.     • The "$X..." must NOT be preceded by a "±".
  368.  
  369.         This eliminates the possibility of modifying the offset of a PC-relative
  370.         addressing mode always generated in the form "*±$XXXX".
  371.     
  372.     • The "$X..." must NOT be preceded by a "#".
  373.     
  374.         This eliminates modifying immediate data.
  375.  
  376.     • Value must be negative.
  377.  
  378.         Negative values are the only values we modify.  A value $FFFF is modified to
  379.         -$0001.
  380.     */
  381.     
  382.     
  383. extern char *validMacsBugSymbol(char *symStart, void *limit,
  384.                                                                 char *symbol);
  385.     /*
  386.     Check that the bytes pointed to by symStart represents a valid MacsBug symbol.
  387.     The symbol must be fully contained in the bytes starting at symStart, up to,
  388.     but not including, the byte pointed to by the limit parameter.
  389.     
  390.     If a valid symbol is NOT found, then NULL is returned as the function's result.
  391.     However, if a valid symbol is found, it is copied to symbol (if it is not NULL)
  392.     as a null terminated Pascal String, and return a pointer to where we think the
  393.     FOLLOWING module begins. In the "old style" cases (see below) this will always
  394.     be 8 or 16 bytes after the input symStart.  For new style Apple Pascal and C
  395.     cases this will depend on the symbol length, existence of a pad byte, and size
  396.     of the constant (literal) area.  In all cases, trailing blanks are removed from
  397.     the symbol.
  398.     
  399.     A valid MacsBug symbol consists of the characters '_', '%', spaces, digits, and
  400.     upper/lower case letters in a format determined by the first two bytes of the
  401.     symbol as follows:
  402.     
  403.      1st byte  | 2nd byte  |  Byte  |
  404.          Range   |  Range    | Length | Comments
  405.     ==============================================================================
  406.      $20 - $7F | $20 - $7F |    8   | "Old style" MacsBug symbol format
  407.      $A0 - $7F | $20 - $7F |    8   | "Old style" MacsBug symbol format
  408.     ------------------------------------------------------------------------------
  409.      $20 - $7F | $80 - $FF |   16   | "Old style" MacApp symbol ab==>b.a
  410.      $A0 - $7F | $80 - $FF |   16   | "Old style" MacApp symbol ab==>b.a
  411.     ------------------------------------------------------------------------------
  412.      $80       | $01 - $FF |    n   | n = 2nd byte       (Apple Compiler symbol)
  413.      $81 - $9F | $00 - $FF |    m   | m = 1st byte & $7F (Apple Compiler symbol)
  414.     ==============================================================================
  415.     
  416.     The formats are determined by whether bit 7 is set in the first and second
  417.     bytes.  This bit will removed when we find it or'ed into the first and/or
  418.     second valid symbol characters.
  419.     
  420.     The first two formats in the above table are the basic "old style" (pre-
  421.     existing) MacsBug formats. The first byte may or may not have bit 7 set the
  422.     second byte is a valid symbol character.  The first byte (with bit 7 removed)
  423.     and the next 7 bytes are assumed to comprise the symbol.
  424.     
  425.     The second pair of formats are also "old style" formats, but used for MacApp
  426.     symbols.  Bit 7 set in the second character indicates these formats. The symbol
  427.     is assumed to be 16 bytes with the second 8 bytes preceding the first 8 bytes
  428.     in the generated symbol.  For example, 12345678abcdefgh represents the symbol
  429.     abcdefgh.12345678.
  430.     
  431.     The last pair of formats are reserved by Apple and generated by the MPW Pascal
  432.     and C compilers.  In these cases the value of the first byte is always between
  433.     $80 and $9F, or with bit 7 removed, between $00 and $1F.  For $00, the second
  434.     byte is the length of the symbol with that many bytes following the second
  435.     byte (thus a max length of 255). Values $01 to $1F represent the length itself.
  436.     A pad byte may follow these variable length cases if the symbol does not end
  437.     on a word boundary.  Following the symbol and the possible pad byte is a word
  438.     containing the size of the constants (literals) generated by the compiler.
  439.     
  440.     Note that if symStart actually does CPoint to a valid MacsBug symbol, then you
  441.     may use showMacsBugSymbol to convert the MacsBug symbol bytes to a String that
  442.     could be used as a DC.B operand for disassembly purposes.  This String
  443.     explicitly shows the MacsBug symbol encodings.
  444.     */
  445.  
  446.  
  447. extern char *endOfModule(void *address, void *limit, char *symbol,
  448.                                                  void **nextModule);
  449.     /*
  450.     Check to see if the specified memory address, contains a RTS, JMP (A0) or
  451.     RTD #n instruction immediately followed by a valid MacsBug symbol.  These
  452.     sequences are the only ones which can determine an end of module when MacsBug
  453.     symbols are present.  During the check, the instruction and its following
  454.     MacsBug symbol must be fully contained in the bytes starting at the specified
  455.     address parameter, up to, but not including, the byte pointed to by the limit
  456.     parameter.
  457.  
  458.     If the end of module is NOT found, then NULL is returned as the function's
  459.     result.  However, if a end of module is found, the MacsBug symbol is returned
  460.     in symbol (if it is not NULL) as a null terminated Pascal String (with trailing
  461.     blanks removed), and the functions returns the pointer to the start of the
  462.     MacsBug symbol (i.e., address+2 for RTS or JMP (A0) and address+4 for RTD #n).
  463.     This address may then be used as in input parameter to showMacsBugSymbol to
  464.     convert the MacsBug symbol to a Disassembler operand String.
  465.     
  466.     Also returned in nextModule is where we think the FOLLOWING module begins. In
  467.     the "old style" cases (see validMacsBugSymbol) this will always be 8 or 16
  468.     bytes after the input address.  For new style the Apple Pascal and C cases this
  469.     will depend on the symbol length, existence of a pad byte, and size of the
  470.     constant (literal) area.  See validMacsBugSymbol for a description of valid
  471.     MacsBug symbol formats. 
  472.     */
  473.     
  474.  
  475. extern char *showMacsBugSymbol(char *symStart, void *limit, char *operand,
  476.                                                              short& bytesUsed);
  477.     /*
  478.     Format a MacsBug symbol as a operand of a DC.B directive.  The first one or two
  479.     bytes of the symbol are generated as $80+'c' if they have there high high bits
  480.     set.  All other characters are shown as characters in a String constant.  The
  481.     pad byte, if present, is one is also shown as $00.
  482.     
  483.     This routine is called to check that the bytes pointed to by symStart represent
  484.     a valid MacsBug symbol.  The symbol must be fully contained in the bytes
  485.     starting at symStart, up to, but not including the byte pointed to by the limit
  486.     parameter.
  487.     
  488.     When called, showMacsBugSymbol assumes that symStart is pointing at a valid
  489.     MacsBug symbol as validated by the validMacsBugSymbol or endOfModule routines.
  490.     As with validMacsBugSymbol, the symbol must be fully contained in the bytes
  491.     starting at symStart up to, but not including, the byte pointed to by the end
  492.     parameter.
  493.     
  494.     The String is returned in the 'operand' parameter as a null terminated Pascal
  495.     String.  The function also returns a pointer to this String as its return
  496.     value (NULL is returned only if the byte pointed to by the limit parameter is
  497.     reached prior to processing the entire symbol -- which should not happen if
  498.     properly validated).  The number of bytes used for the symbol is returned in
  499.     bytesUsed.  Due to the way MacsBug symbols are encoded, bytesUsed may not
  500.     necessarily be the same as the length of the operand String.
  501.     
  502.     A valid MacsBug symbol consists of the characters '_', '%', spaces, digits, and
  503.     upper/lower case letters in a format determined by the first two bytes of the
  504.     symbol as described in the validMacsBugSymbol routine.
  505.     */
  506.  
  507. #ifdef __cplusplus
  508. }
  509. #endif
  510. #endif
  511.